#Region - Header
;***********************;******************
;Gnomoria_Enhanced.au3 by Billy 'bvierra' Vierra
;Created with ISN AutoIt Studio v. 0.8 BETA
;*****************************************
#EndRegion

#Region AutoIt3Wrapper directives section
;** This is a list of compiler directives used by AutoIt3Wrapper.exe.
;** comment the lines you don't need or else it will override the default settings
;===============================================================================================================
;** AUTOIT3 settings
#AutoIt3Wrapper_UseX64=N                         ;(Y/N) Use X64 versions for AutoIt3_x64 or AUT2EXE_x64. Default=N
#AutoIt3Wrapper_Version=P                        ;(B/P) Use Beta or Production for AutoIt3 and AUT2EXE. Default is P
;~ #AutoIt3Wrapper_Run_Debug_Mode=N                 ;(Y/N) Run Script with console debugging. Default=N
#AutoIt3Wrapper_Run_SciTE_Minimized=N            ;(Y/N) Minimize SciTE while script is running. Default=n
#AutoIt3Wrapper_Run_SciTE_OutputPane_Minimized=N ;(Y/N) Toggle SciTE output pane at run time so its not shown. Default=n
;===============================================================================================================
;~ ;** AUT2EXE settings
;~ #AutoIt3Wrapper_Icon=                           ;Filename of the Ico file to use
;~ #AutoIt3Wrapper_OutFile=                        ;Target exe/a3x filename.
;~ #AutoIt3Wrapper_OutFile_Type=                   ;a3x=small AutoIt3 file;  exe=Standalone executable (Default)
;~ #AutoIt3Wrapper_OutFile_X64=                    ;Target exe filename for X64 compile.
;~ #AutoIt3Wrapper_Compression=                    ;Compression parameter 0-4  0=Low 2=normal 4=High. Default=2
;~ #AutoIt3Wrapper_UseUpx=                         ;(Y/N) Compress output program.  Default=Y
;~ #AutoIt3Wrapper_UPX_Parameters=                 ;Override the default setting for UPX.
;~ #AutoIt3Wrapper_Change2CUI=                     ;(Y/N) Change output program to CUI in stead of GUI. Default=N
;~ #AutoIt3Wrapper_Compile_both=                   ;(Y/N) Compile both X86 and X64 in one run. Default=N
;~ ;===============================================================================================================
;~ ;** Target program Resource info
#AutoIt3Wrapper_Res_Comment=Alpha                   ;Comment field
#AutoIt3Wrapper_Res_Description=Adds additional funtionality to Gnomoria                ;Description field
#AutoIt3Wrapper_Res_Fileversion=0.1.0                ;File Version
;~ #AutoIt3Wrapper_Res_FileVersion_AutoIncrement=P  ;(Y/N/P) AutoIncrement FileVersion After Aut2EXE is finished. default=N
#AutoIt3Wrapper_Res_LegalCopyright=Copyright 2012 Billy 'bvierra' Vierra              ;Copyright field
#AutoIt3Wrapper_res_requestedExecutionLevel=N    ;None, asInvoker, highestAvailable or requireAdministrator   (default=None)
#AutoIt3Wrapper_Res_SaveSource=N                 ;(Y/N) Save a copy of the Scriptsource in the EXE resources. default=N
;~ ;===============================================================================================================
;~ ; Tidy Settings
#AutoIt3Wrapper_Run_Tidy=Y                       ;(Y/N) Run Tidy before compilation. default=N
#AutoIt3Wrapper_Tidy_Stop_OnError=Y              ;(Y/N) Continue when only Warnings. default=Y
;~ #Tidy_Parameters=                               ;Tidy Parameters...see SciTE4AutoIt3 Helpfile for options
;~ ;===============================================================================================================
;~ ; Obfuscator
#AutoIt3Wrapper_Run_Obfuscator=N                 ;(Y/N) Run Obfuscator before compilation. default=N
;~ #obfuscator_parameters=/SF=1 /SV=1						; http://www.autoitscript.com/autoit3/scite/docs/Obfuscator_doc.htm
;~ ;===============================================================================================================
;~ ; AU3Check settings
#AutoIt3Wrapper_Run_AU3Check=Y                   ;(Y/N) Run au3check before compilation. Default=Y
;~ #AutoIt3Wrapper_AU3Check_Parameters=            ;Au3Check parameters
;~ #AutoIt3Wrapper_AU3Check_Stop_OnWarning=        ;(Y/N) N=Continue on Warnings.(Default) Y=Always stop on Warnings
;~ #AutoIt3Wrapper_PlugIn_Funcs=                   ;Define PlugIn function names separated by a Comma to avoid AU3Check errors
;~ ;===============================================================================================================
;~ ; RUN BEFORE AND AFTER definitions
;~ ; The following directives can contain: these variables
;~ ;   %in% , %out%, %outx64%, %icon% which will be replaced by the fullpath\filename.
;~ ;   %scriptdir% same as @ScriptDir and %scriptfile% = filename without extension.
;~ ;   %fileversion% is the information from the #AutoIt3Wrapper_Res_Fileversion directive
;~ ;   %scitedir% will be replaced by the SciTE program directory
;~ ;   %autoitdir% will be replaced by the AutoIt3 program directory
;~ #AutoIt3Wrapper_Run_Before=                     ;process to run before compilation - you can have multiple records that will be processed in sequence
;~ #AutoIt3Wrapper_Run_After=                      ;process to run After compilation - you can have multiple records that will be processed in sequence
;~ ;===============================================================================================================
;~ ; RUN BEFORE AND AFTER definitions
;~ #AutoIt3Wrapper_Add_Constants=                  ;Add the needed standard constant include files. Will only run one time.
#EndRegion

#NoTrayIcon

#Region - AutoIt Includes (1/2)
;*****************************************
; AutoIT Includes
;*****************************************
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <Misc.au3>
#include <Constants.au3>
#endregion

#Region - Variables
Opt("GUIOnEventMode", 1) ; Change to OnEvent mode for GUI
_Singleton('GnomoriaEnhanced') ; Only let 1 instance of Gnormoria Enhanced run at a time
;*****************************************
; Variables
;*****************************************
; Program & Build Information
Global $programVersionBuild = "2012062901" ;YEAR|MON|DAY|BUILD# | Update this for build
Global $programVersionName = "0.1 ALPHA"
Global $programName = "Gnomoria Enhanced"

; Global Configuration Constants
Global $basePath = @MyDocumentsDir & "\My Games\Gnomoria"
Global $savesPath = $basePath & "\Worlds"
Global $addonsPath = $basePath & "\Addons"
Global $myPath = $addonsPath & "\Gnomoria Enhanced"
Global $myLogsPath = $myPath & "\logs"
Global $myDataPath = $myPath & "\data"
Global $backupSavesPath = $myDataPath & "\WorldsBackup"
Global $backupSavesConfigFile = $backupSavesPath & "\backups.ini"
Global $configFile = $myPath & "\gnomoriaenhanced.ini"
Global $gnomoriaLogFile = $basePath & "\Gnomoria.log"
Global $gnomoriaProcessName = "Gnomoria.exe"

; Config Defaults
Global $debug = 0
$debug = _configRead("debug",0,1)
Global $logTray = _configRead("logTray",1,1)
Global $logConsole = _configRead("logConsole",9,1)
Global $maxTimeDiff = 60 * 30 ; 60 seconds * 30 min
Global $gnomoriaDirectory = _configRead("gnomoriaDirectory","c:\Gnomoria")
Global $tmpDir = $myPath & "\tmp"
Global $computerHash = _configRead("computerHash","")
Global $computerName = _configRead("computerName","")
Global $geApiUrl = _configRead("geApiUrl","http://ge.gnomoriawiki.com/api")

; Update Information
Global $updateProtocol = "http"
Global $updateDomain = "ge.gnomoriawiki.com"
Global $updateDir = $updateProtocol & "://" & $updateDomain & "/releases"
Global $updateVersionFile = _configRead("updateVersionFile",$updateDir & "/version")
Global $updateTimeLastCheck = _configRead("updateTimeLastCheck","1970/01/01 00:00:00") ; Epoch 0 (1/1/1970)
Global $updateCheckFreq = _configRead("updateCheckFreq",86400) ; 1 day
Global $updateNextCheck, $updateTimer

; General Variables
Global $updateComputerHash = 0
Global $gnomoriaRunning = 0
Global $gnomoriaPid
Global $gnomoriaHandle

#EndRegion

#Region - Script Includes (2/2)
;*****************************************
; Script Includes
;*****************************************
#include <GUI\About.au3>
#include <GUI\Settings.au3>

#include <lib\Base64.au3>
#include <lib\HTTP.au3>
#include <lib\HTTPPostFiles.au3>
#include <lib\ProcessExitCode.au3>
#Include <lib\Restart.au3>
#include <lib\Zip.au3>

#include <Api.au3>
#include <gnomoria.au3>
#include <Identification.au3>
#include <updater.au3>
#EndRegion

#Region - Startup Check
;*****************************************
; Create Directories
;*****************************************
DirCreate($addonsPath)
DirCreate($myPath)
DirCreate($myLogsPath)
DirCreate($tmpDir)
DirCreate($myDataPath)
DirCreate($backupSavesPath)

If @Compiled Then
	If @ScriptFullPath <> $myPath & "/gnomoriaenhanced.exe" Then
		FileMove(@ScriptFullPath,$myPath & "/gnomoriaenhanced.exe")
	EndIf
EndIf
_checkGnomoriaPath()

_checkApi()


;*****************************************
; Verify unique computer ID exists and has not been changed
;*****************************************
If Not $computerName Or $computerName <> @ComputerName Then
	warn("Either computer name has been changed or this is your first time running Gnomoria Enhanced")
	$computerName = @ComputerName
	_configWrite("computerName",$computerName)
	$updateComputerId = 1
EndIf
If Not $computerHash Or $updateComputerHash Then
	warn("Either your computerId has been tampered with or this is your first time running Gnomoria Enhanced")
	$computerHash = _generateComputerId()
	_configWrite("computerHash",$computerHash)
	$updateComputerId = 0
EndIf

#EndRegion

#Region - TrayMenu
;*****************************************
; TrayMenu
;*****************************************
Opt("TrayMenuMode", 3) ; Default tray menu items (Script Paused/Exit) will not be shown, check marks are not shown
Opt("TrayAutoPause", 0) ; Program does not pause on tray click
Opt("TrayOnEventMode", 1) ; Turns on the on event mode for the tray
TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "_runGnomoriaTray") ; Runs Gnomoria on double click
TrayCreateItem($programName & " Version: " & $programVersionName)
TrayCreateItem("")
TrayCreateItem("Play Gnomoria")
TrayItemSetOnEvent(-1, "_runGnomoriaTray")
TrayCreateItem("")
TrayCreateItem("Check for update")
TrayItemSetOnEvent(-1, "_updateCheckTray")
TrayCreateItem("")
TrayCreateItem("Settings")
TrayItemSetOnEvent(-1, "_guiSettings")
TrayCreateItem("About")
TrayItemSetOnEvent(-1, "_guiAbout")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "_Exit")
TraySetState()

#EndRegion

#Region - Main Wait Loop
info("Gnomoria Enhanced Started")

_updateSetTimer() ; Sets the timer to next update check time
While 1
	Sleep(10)
	If TimerDiff($updateTimer) >= $updateNextCheck Then _updateCheck()
	If $gnomoriaRunning Then
		Local $pid = ProcessExists($gnomoriaProcessName)
		If $pid = 0 Then
			Local $iExitCode = _ProcessGetExitCode($gnomoriaHandle)
			_ProcessCloseHandle($gnomoriaHandle)
			$gnomoriaRunning = 0
			debug("Gnomoria Exit Code: " & $iExitCode)
			If $iExitCode Then _gnomoriaCrash()
		EndIf
	EndIf
WEnd
#EndRegion

#Region - Functions - Tray Events
;*****************************************
; Tray Event Functions
;*****************************************
Func _runGnomoriaTray()
	$gnomoriaPid = _runGnomoria()
	debug("Gnomoria started with PID: " & $gnomoriaPid)
	$gnomoriaHandle = _ProcessGetHandle($gnomoriaPid)
EndFunc

Func _updateCheckTray()
	_updateCheck(1)
EndFunc

Func _Exit()
	info("Closing Gnomoria Enhanced" & @CRLF)
	Exit
EndFunc
#EndRegion

#Region - Functions - General
;*****************************************
; General Functions
;*****************************************

Func _parseJson($prefix,$data)
	Local $array = StringSplit ( $data, ",",1)
	Local $i = 1
	While $i <= UBound($array) - 1
		Local $a = StringSplit($array[$i],":")
		Local $key = StringRegExpReplace($a[1],'["]',"")
		Local $val = StringRegExpReplace($a[2],'["]',"")
		Assign($prefix & "_" & $key,$val)
		debug("[" & $prefix & "_" & $key & "] " & $val)
		$i = $i + 1
	WEnd
EndFunc

Func _checkApi()
	Local $geApiStatusUrl = $geApiUrl & "/status"
	Global $api_running,$api_version
	debug("Checking API Status...")
	Local $sData = _apiCall($geApiStatusUrl)
	If @error Then
		warn("[" & $api_running & "] API (" & $geApiStatusUrl & ") seems to be down. Returned Status Code: " & @extended)
		Return 0
	EndIf
	_parseJson("api",$sData)
	If Not $api_running = 1 Then
		warn("[" & $api_running & "] API Status seems to be down for: " & $geApiStatusUrl)
		Return 0
	EndIf
	debug("API seems to be running fine")
	Return 1
EndFunc
#EndRegion

#Region - Functions - Config
;*****************************************
; Config Functions
;*****************************************
Func _configRead($key, $default, $nolog = 0)
	$i = iniread($configFile, "General", $key, $default)
	If $nolog = 0 Then debug("[" & $key & "]" & $i)
	return $i
EndFunc

Func _configWrite($key, $value)
	iniwrite($configFile, "General", $key, $value)
EndFunc

#EndRegion

#Region - Functions - Logging
;*****************************************
; Logging Functions
;*****************************************
Func logMsg($level = 1, $txt = '', $title = -1)
	If $debug = 1 Then $lvl = 0
	If $title = -1 Then $title = $programName & " " & $programVersionName
	If $logTray <= $level Then TrayTip($title, $txt, 1500, $level)
	If (Not @Compiled) Then
		If $logConsole <= $level Or $debug = 1 Then 
			ConsoleWrite($txt & @CRLF)
		EndIf
	EndIf
	; TODO Add in file log
EndFunc ;==>logMsg

Func debug($txt = '', $title = -1)
	logMsg(0,$txt,$title)
EndFunc
Func info($txt = '', $title = -1)
	logMsg(1,$txt,$title)
EndFunc
Func warn($txt = '', $title = -1)
	logMsg(2,$txt,$title)
EndFunc
Func error($txt = '', $title = -1)
	logMsg(3,$txt,$title)
EndFunc
#EndRegion

#Region - Functions - Startup and Verification
;*****************************************
; Startup and verification Functions
;*****************************************
Func _checkGnomoriaPath()
	If FileExists($gnomoriaDirectory & "\Gnomoria.exe") Then Return
	Local $selected
	Do 
		$selected = FileSelectFolder ("Select Gnomoria Install Folder", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 6, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")	
 		debug("Checking " & $selected & "\Gnomoria.exe" & @CRLF)
	Until FileExists($selected & "\Gnomoria.exe") = 1
	$gnomoriaDirectory = $selected
	_configWrite("gnomoriaDirectory",$gnomoriaDirectory)
EndFunc
#EndRegion